import cgi, os
import cgitb
cgitb.enable() # as recommended by the CGI tutorial at http://www.penzilla.net/tutorials/python/cgi/
import os
import random
import re
import string
import sys

class CgiApplication:
    def __init__(self, workspaceDirectory):
        self.randid = random.randint(0,1000000)
        self.form = cgi.FieldStorage()
        
        # as recommended by: http://webpython.codepoint.net/big_file_upload
        try: # Windows needs stdio set for binary mode.
            import msvcrt
            msvcrt.setmode (0, os.O_BINARY) # stdin  = 0
            msvcrt.setmode (1, os.O_BINARY) # stdout = 1
        except ImportError:
            pass
    
    def printHtmlHeader(self):
        print "Content-type: text/html\n\n"
        print "<html>"
        print "<head>"
        print "<link rel='stylesheet' href='cleanscience1.css'>"
        print "</head>"
        print "<body>"
        print "<p>PhyloWidgets header goes here.</p>"
        print "<hr>"
        
    def printHtmlFooter(self):
        print ""
        print "</body>"
        print "</html>"
        
    def throwError(self, message):
        self.printHtmlHeader()
        print "<p><strong>Yikes!</strong> Something went wrong.</p>"
        print "<p>" + message + "</p>"
        self.printHtmlFooter()
        exit()
    
    def getItem(self, key):
        if self.form.has_key( key ):
            if self.form[key] == None:
                displayError("I was expecting an HTML form item named '" + key + "', but I didn't find it.  Perhaps your HTML page is out-of-date?")
            return self.form[ key ].value
        else:
            displayError("I was expecting an HTML form item named '" + key + "', but I didn't find it.  Perhaps your HTML page is out-of-date?")
    
    def getOptionalItem(self, key):
        if self.form.has_key( key ):
            if self.form[key] == None:
                return False
            return self.form[ key ].value
        else:
            return False
    
    def getFile(self, key):
        if self.form.has_key(key):
            input = ""
            fileitem = self.form[key]
            if fileitem.filename:
                # strip leading path from file name to avoid directory traversal attacks
                fn = os.path.basename(fileitem.filename)
                # Read the file in chunks
                for chunk in self.fbuffer(fileitem.file):
                    input += chunk
                return input
            else:
                return False
        else:
            return False       
    
    def displayError(self, message):
        print "<p><strong>Yikes!</strong> Something went wrong:</p>"
        print "<p>" + message + "</p>"
        exit()
        
    # Generator to buffer file chunks
    def fbuffer(self, f, chunk_size=10000):
        while True:
            chunk = f.read(chunk_size)
            if not chunk: 
                break
            yield chunk
            
    # parse the HTML form; print each key and it's value
    def spewForm(self):
        # Print all the keys and their values
        for k in self.form.keys():
            print "<p>KEY:</p>" + k
            print "<p>CONTENT:</p>" + self.form[k].value.__str__()
            
    def getEnvValue(self, value):
        env = os.environ
        return env[value]
    
    
    def isSSL(self):
        #""" Return true if we are on a SSL (https) connection. """
        return os.environ.get('SSL_PROTOCOL', '') != ''
    
    
    def getScriptname(self):
        #""" Return the scriptname part of the URL ("/path/to/my.cgi"). """
        return os.environ.get('SCRIPT_NAME', '')
    
    
    def getPathinfo(self):
        #""" Return the remaining part of the URL. """
        pathinfo = os.environ.get('PATH_INFO', '')
    
        # Fix for bug in IIS/4.0
        if os.name == 'nt':
            scriptname = self.getScriptname()
            if string.find(pathinfo, scriptname) == 0:
                pathinfo = pathinfo[len(scriptname):]                
        
        return pathinfo

    def getQualifiedURL(self, uri = None):
        #""" Return a full URL starting with schema, servername and port.
        #
        #    *uri* -- append this server-rooted uri (must start with a slash)
        #"""
        schema, stdport = (('http', '80'), ('https', '443'))[self.isSSL()]
        host = self.getEnvValue('HTTP_HOST')
        if not host:
            host = self.getEnvValue('SERVER_NAME')
            port = self.getEnvValue('SERVER_PORT', '80')
            if port != stdport: host = host + ":" + port
    
        result = "%s://%s" % (schema, host)
        if uri: result = result + uri
        
        return result
    
    def getBaseURL(self):
        #Return a fully qualified URL to this script. """
        return self.getQualifiedURL(self.getScriptname())
    
    def getDirectoryURL(self):
        x = self.getBaseURL()
        y = x.split("/")
        z = ""
        for i in range(0, y.__len__() - 1):
            z += y[i] + "/"
        return z